﻿using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.IO;

namespace ConsoleApplication1
{
    class ReglaOperadores : Regla
    {

        //Atributos

        private int _tipo;

 
        //Propiedades

        public int Tipo
        {
            get { return _tipo; }
            set { _tipo = value; }
        }
       
        //Metodos
        public ReglaOperadores(int tipo)
        {
            //Constructor
            Tipo = tipo; 
        }

        private bool SoloOperadores (string subcadena)
            //Regresa true si se encontraron solo operadores en la sub cadena y False si no. 
        {
            int i = 0;
            int ancho = subcadena.Length;
            char[] operadores = {'=','!','<','>','~','+','-','*','/','%','^','<','&','|','?'};
            int flagOperadores = 0;
            try
            {
                while (i < ancho){
                    flagOperadores = 0;
                    foreach(char a in operadores)
                    {
                        if( subcadena[i] == a)
                        {
                            flagOperadores = 1;
                        }
                    }
                    if (flagOperadores == 0)
                        return false;
                    i++;
                }
                return true;
            }catch(Exception e){
                Console.WriteLine(e.Message);
                return false;
            }
        }

        private bool SoloNoOperadores(string subcadena)
        //Regresa true si se encontraron solo caracteres no operadores en la suba cadena y False si no. 
        {
            int i = 0;
            int ancho = subcadena.Length;
            char[] operadores = { '=', '!', '<', '>', '~', '+', '-', '*', '/', '%', '^', '<', '&', '|', '?'};
            int flagOperadores = 0;
            int flagAux = 0;
            try
            {
                while (i < ancho)
                {
                    foreach (char a in operadores)
                    {
                        if (subcadena[i] == a)
                        {
                            return false;
                        }
                    }
                    flagOperadores = flagAux;
                    i++;
                }
                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return false;
            }
        }


         public Resultado regla_OperadoresCE(ArrayList archivo)
             //Revisa si los operadores tienen espacio antes y despues.
             //Ejemplo: i = 1;  if(r <= 3)
         {
             int LineaActual = 0; //Linea actual que se esta leyendo.
             Resultado Resp = new Resultado(); //Objeto resultado que sera retornado.


             //Inicializamos Resp asumiendo que el archivo cumple con la regla.
             Resp.Fecha = new DateTime();
             Resp.Fecha = DateTime.Now;
             Resp.Respuesta = true;
             Resp.Mensaje = "No se encontraron errores";
             Resp.Linea = 0;

             try
             {
                 foreach (string linea in archivo) //Recorro la lista linea por linea
                 {
                     LineaActual++;
                     string[] subCadenas = linea.Split(' '); //Separamos la linea por espacios.
                     foreach (string sc in subCadenas)       //Por cada sub cadena  
                     {
                         if (SoloNoOperadores(sc) == false) //Si la subcadena contiene operadores
                         {
                             if (SoloOperadores(sc) == false)   //Checkeamos que la cadena contenga operadores y letras.
                             {
                                 Resp.Linea = LineaActual;
                                 Resp.Respuesta = false;
                                 Resp.Mensaje = "Se olvido separar un operador en la linea " + LineaActual;
                                 return Resp;
                             }
                         }
                     }// end foreach(subcadena en linea)
                     
                 } // foreach(linea in archivo)
                 return Resp; //Retornamos Respuesta
             }// End Try
             catch (Exception e)
             {
                 Resp.Linea = LineaActual;
                 Resp.Respuesta = false;
                 Resp.Mensaje = "Ocurrio un error inesperado al leer la linea " + LineaActual + ". Error " + e.Message;
                 return Resp;
             }
             
         }

         public Resultado regla_OperadoresSE(ArrayList archivo)
             //Revisa si los operadores no tienen espacios ni antes ni despues de ellos
             //Ejemplo: i=1;   if(r<=3)
         {
             int LineaActual = 0; //Linea actual que se esta leyendo.
             Resultado Resp = new Resultado(); //Objeto resultado que sera retornado.
             char[] operadores = { '=', '!', '<', '>', '~', '+', '-', '*', '/', '%', '^', '<', '&', '|', '?' }; //Arreglo con todos los operadores.
             int flagAux = 0; //Bandera que se utilizara para ver si se encontró operadores.
             //Inicializamos Resp asumiendo que el archivo cumple con la regla.
             Resp.Fecha = new DateTime();
             Resp.Fecha = DateTime.Now;
             Resp.Respuesta = true;
             Resp.Mensaje = "No se encontraron errores";
             Resp.Linea = 0;

             try
             {
                 foreach (string linea in archivo) //Recorro la lista linea por linea
                 {
                     LineaActual++;
                     string[] subCadenas = linea.Split(' '); //Separamos la linea por espacios.
                     foreach (string sc in subCadenas)       //Por cada sub cadena  
                     {
                         foreach (char a in operadores) //Checkeamos que si existe un operador en el primer caracter de la sub cadena
                         {
                             if (sc.Length > 0)
                                if (sc[0] == a)
                                    flagAux = 1;
                         }
                         if (flagAux == 1)
                         {
                             Resp.Linea = LineaActual;
                             Resp.Respuesta = false;
                             Resp.Mensaje = "Se separó un operador en la linea " + LineaActual;
                             return Resp;
                         }
                         foreach (char a in operadores) //Checkeamos que si existe un operador en el ultimo caracter de la sub cadena
                         {
                             if (sc.Length > 0)
                                if (sc[sc.Length - 1] == a)
                                    flagAux = 1;
                         }
                         if (flagAux == 1)
                         {
                             Resp.Linea = LineaActual;
                             Resp.Respuesta = false;
                             Resp.Mensaje = "Se separó un operador en la linea " + LineaActual;
                             return Resp;
                         }
                     }// end foreach(subcadena en linea)
                     
                 } // foreach(linea in archivo)
                 return Resp; //Retornamos Respuesta
             }// End Try
             catch (Exception e)
             {
                 Resp.Linea = LineaActual;
                 Resp.Respuesta = false;
                 Resp.Mensaje = "Ocurrio un error inesperado al leer la linea " + LineaActual + ". Error " + e.Message;
                 return Resp;
             }

         }

        override public Resultado Aplicar(ArrayList archivo)
        {
            try
            {
                if (Tipo == 1)
                    return regla_OperadoresCE(archivo);
                if (Tipo == 2)
                    return regla_OperadoresSE(archivo);
                return null;              
            }
            catch (Exception e)
            {
                return null;
            }
        }

        

    }
}
